/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.auth;

import com.je.auth.check.exception.ApiDisabledException;
import com.je.auth.check.exception.NotLoginException;
import com.je.auth.impl.AbstractAuthLoginManagerImpl;
import com.je.auth.stp.AuthTokenInfo;
import com.je.auth.util.JwtUtil;
import java.util.List;
import java.util.Map;

/**
 * 整合 jwt -- Mix 混入
 *
 * @author kong
 */
public class MixJwtAuthLoginManagerImpl extends AbstractAuthLoginManagerImpl {

    /**
     * 获取jwt秘钥
     *
     * @return /
     */
    public String jwtSecretKey() {
        return getConfig().getJwtSecretKey();
    }

    //
    // ------ 重写方法
    //

    // ------------------- 获取token 相关 -------------------

    /**
     * 创建一个TokenValue
     */
    @Override
    public String createTokenValue(Object loginId, String device, long timeout, Map<String, Object> extraData) {
        return JwtUtil.createToken(loginId, device, timeout, extraData, jwtSecretKey());
    }

    /**
     * 获取当前会话的Token信息
     *
     * @return token信息
     */
    @Override
    public AuthTokenInfo getTokenInfo() {
        AuthTokenInfo info = new AuthTokenInfo();
        info.tokenName = getTokenName();
        info.tokenValue = getTokenValue();
        info.isLogin = isLogin();
        info.loginId = getLoginIdDefaultNull();
        info.tokenTimeout = getTokenTimeout();
        info.sessionTimeout = AuthTokenDao.NOT_VALUE_EXPIRE;
        info.tokenSessionTimeout = AuthTokenDao.NOT_VALUE_EXPIRE;
        info.tokenActivityTimeout = AuthTokenDao.NOT_VALUE_EXPIRE;
        info.loginDevice = getLoginDevice();
        return info;
    }

    // ------------------- 登录相关操作 -------------------

    /**
     * 获取指定Token对应的账号id (不做任何特殊处理)
     */
    @Override
    public String getLoginIdNotHandle(String tokenValue) {
        // 获取 loginId
        try {
            Object loginId = JwtUtil.getLoginId(tokenValue, jwtSecretKey());
            return String.valueOf(loginId);
        } catch (NotLoginException e) {
            return null;
        }
    }

    /**
     * 会话注销
     */
    @Override
    public void logout() {
        // 从当前 [storage存储器] 里删除
        getAuthEngine().getAuthCheckEngine().getAuthTokenContext().getStorage().delete(splicingKeyJustCreatedSave());
        // 如果打开了Cookie模式，则把cookie清除掉
        if (getAuthEngine().getAuthCheckEngine().getConfig().getIsReadCookie()) {
            getAuthEngine().getAuthCheckEngine().getAuthTokenContext().getResponse().deleteCookie(getTokenName());
        }
    }

    /**
     * [禁用] 会话注销，根据账号id 和 设备标识
     */
    @Override
    public void logout(Object loginId, String device) {
        throw new ApiDisabledException();
    }

    /**
     * [禁用] 会话注销，根据指定 Token
     */
    @Override
    public void logoutByTokenValue(String tokenValue) {
        throw new ApiDisabledException();
    }

    /**
     * [禁用] 踢人下线，根据账号id 和 设备标识
     */
    @Override
    public void kickout(Object loginId, String device) {
        throw new ApiDisabledException();
    }

    /**
     * [禁用] 踢人下线，根据指定 Token
     */
    @Override
    public void kickoutByTokenValue(String tokenValue) {
        throw new ApiDisabledException();
    }

    /**
     * [禁用] 顶人下线，根据账号id 和 设备标识
     */
    @Override
    public void replaced(Object loginId, String device) {
        throw new ApiDisabledException();
    }

    /**
     * 获取Token携带的扩展信息
     */
    @Override
    public Object getExtra(String key) {
        return JwtUtil.getPayloads(getTokenValue(), jwtSecretKey()).get(key);
    }

    /**
     * 删除 Token-Id 映射
     */
    @Override
    public void deleteTokenToIdMapping(String tokenValue) {
        // not action
    }

    /**
     * 更改 Token 指向的 账号Id 值
     */
    @Override
    public void updateTokenToIdMapping(String tokenValue, Object loginId) {
        // not action
    }

    /**
     * 存储 Token-Id 映射
     */
    @Override
    public void saveTokenToIdMapping(String tokenValue, Object loginId, long timeout) {
        // not action
    }

    // ------------------- 过期时间相关 -------------------

    /**
     * 获取当前登录者的 token 剩余有效时间 (单位: 秒)
     */
    @Override
    public long getTokenTimeout() {
        return JwtUtil.getTimeout(getTokenValue(), jwtSecretKey());
    }

    // ------------------- 会话管理 -------------------

    /**
     * [禁用] 根据条件查询Token
     */
    @Override
    public List<String> searchTokenValue(String keyword, int start, int size) {
        throw new ApiDisabledException();
    }

    // ------------------- Bean对象代理 -------------------

    /**
     * 返回全局配置对象的isShare属性
     *
     * @return /
     */
    @Override
    public boolean getConfigOfIsShare() {
        return false;
    }

}
